﻿using Autofac;
using Autofac.Extras.DynamicProxy;
using Castle.Core.Internal;
using HBKY.Shop.Common;
using HBKY.Shop.Common.Helper;
using HBKY.Shop.Common.RequestAccessor;
using HBKY.Shop.Extensions.AOP;
using HBKY.Shop.Extensions.AuthHelper.RequestAccessor;
using HBKY.Shop.IRepository.Base;
using HBKY.Shop.IRepository.MongoRepository;
using HBKY.Shop.Repository.Base;
using HBKY.Shop.Repository.MongoRepository;
using HBKY.Shop.Service;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace HBKY.Shop.Extensions.CoreBuilder
{
    public class AutofacModuleRegister : Autofac.Module
    {
        /// <summary>
        /// 注册容器
        /// </summary>
        protected override void Load(ContainerBuilder builder)
        {
            var basePath = AppContext.BaseDirectory;
           
            builder.RegisterType<CurrentUser>().As<ICurrentUser>()
                .AsImplementedInterfaces()
                .InstancePerDependency()
                .PropertiesAutowired();
            var cacheType = new List<Type>();

            // AOP 开关，如果想要打开指定的功能，只需要在 appsettigns.json 对应对应 true 就行。
            if (Appsettings.Option("AppSettings", "RedisCachingAOP", "Enabled").ObjToBool())
            {
                builder.RegisterType<ServiceCacheAOP>();
                cacheType.Add(typeof(ServiceCacheAOP));
            }

            #region 带有接口层的服务注入

            var servicesDllFile = Path.Combine(basePath, "HBKY.Shop.Service.dll");
            var repositoryDllFile = Path.Combine(basePath, "HBKY.Shop.Repository.dll");

            if (!(File.Exists(servicesDllFile) && File.Exists(repositoryDllFile))) 
                throw new Exception("Repository.dll和service.dll 丢失");
         
            builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).AsImplementedInterfaces()
                .InstancePerDependency().PropertiesAutowired(); //注册仓储

            builder.RegisterGeneric(typeof(MongoRepository<>)).As(typeof(IMongoRepository<>)).AsImplementedInterfaces()
             .InstancePerDependency().PropertiesAutowired(); //Mongo

            // 获取 Repository.dll 程序集服务，并注册
            var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);
            builder.RegisterAssemblyTypes(assemblysRepository)
                .AsImplementedInterfaces()
                .InstancePerDependency()
                .PropertiesAutowired();

            // 获取 Service.dll 程序集服务，并注册
            var assemblysServices = Assembly.LoadFrom(servicesDllFile);
            builder.RegisterAssemblyTypes(assemblysServices)
                .AsImplementedInterfaces()
                .InstancePerDependency()
                .PropertiesAutowired()
                .EnableInterfaceInterceptors()
                .InterceptedBy(cacheType.ToArray());//允许将拦截器服务的列表分配给注册。;

            var assemblysServicesNoInterfaces = Assembly.Load("HBKY.Shop.Service");
            builder.RegisterTypes(assemblysServicesNoInterfaces.GetTypes().FindAll(o => o.BaseType == typeof(BaseApiService)).ToArray())
                   .InterceptedBy(cacheType.ToArray())
                   .EnableClassInterceptors();

            #endregion
        }
    }
}